package Player;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.Color;
import java.text.MessageFormat;

import Monopol.Monopol;
import Square.Negotiable;
import Square.Square;


/**
 * @author Avia Tam
 * @author Assaf Miron
 *
 */
public abstract class Player {
	private String name; // Player Name
	private Double funds; // The Amount of Money the Player have
	private ArrayList<Square>assets; // The Players Owned Assets
	private Integer game_location; // The Players' location in the Game
	private Boolean release_from_prison_card; // Does the Player have the "Release from Prison" Card
	private Boolean is_in_prison; // Is the Player in Prison of not
	private Boolean is_parking; // Is the Player in Parking
	private Boolean toDelete; // A marker if to Delete the Player
	private Color playerColor; // The Player Color in the Game
	private Integer number;//added in order to locate place on panel
	private Integer id; // Add for Support of Unique ID
	
	public Player()
	{
		super();
		this.name = "Player"; // Initialize the Player Name
		this.funds = 0.0; // Initialize the Players Funds
		this.assets = new ArrayList<Square>(); // Initialize the Assets
		this.assets.clear(); // Clear the Assets List
		this.game_location = new Integer(0); // Set the Player Location to the Beginning
		this.release_from_prison_card = false; // Set that the Player does not have the "Release from Prison" Card
		this.is_in_prison = false; // Set that the Player is not in Prison
		this.is_parking = false; // Set that the Player is not in Parking
		this.toDelete = false; // Initialize that the Player is active
	}
	
	/**
	 * @param name The Players Name
	 * @param funds The Amount of money the Player will get
	 */
	public Player(String name, Double funds) 
	{
		super(); // Construct Object
		this.name = name; // Initialize the Player Name
		this.funds = funds; // Initialize the Players Funds
		this.assets = new ArrayList<Square>(); // Initialize the Assets
		this.assets.clear(); // Clear the Assets List
		this.game_location = new Integer(0); // Set the Player Location to the Beginning
		this.release_from_prison_card = false; // Set that the Player does not have the "Release from Prison" Card
		this.is_in_prison = false; // Set that the Player is not in Prison
		this.is_parking = false; // Set that the Player is not in Parking
		this.toDelete = false; // Initialize that the Player is active
	}
	
	public Player(String name, Double funds, Color playerColor, Integer number)
	{
		super(); // Construct Object
		this.name = name; // Initialize the Player Name
		this.funds = funds; // Initialize the Players Funds
		this.assets = new ArrayList<Square>(); // Initialize the Assets
		this.assets.clear(); // Clear the Assets List
		this.game_location = new Integer(0); // Set the Player Location to the Beginning
		this.release_from_prison_card = false; // Set that the Player does not have the "Release from Prison" Card
		this.is_in_prison = false; // Set that the Player is not in Prison
		this.is_parking = false; // Set that the Player is not in Parking
		this.toDelete = false; // Initialize that the Player is active
		this.playerColor = playerColor; // Initialize the Player Color
		this.number=number;//get the number
		
	}

	public Integer getUniqueID(){
	    return -1;
	}

	public Integer getNumber() {
		return number;
	}

	public void setUniqueID(Integer playerUID){
	    // Implementing Default Values - Implemented in Human Class
	    id = -1;
	}

	public void setNumber(Integer number) {
		this.number = number;
	}

	// Name Getter and Setter
    public String getName() {
	if (name == null) {
	    return "NONE";
	} else {
	    return name;
	}
    }
	
	public void setName(String name) {
		this.name = name;
	}
	// End - Name Getter and Setter
	
	//Funds Getter and Setter
	public Double getFunds() {
		return funds;
	}
	public void addFunds(Double funds)
	{
		this.funds+=funds;
	}

	// End - Funds Getter and Setter
	
	// Assets Getter and Setter
	public ArrayList<Square> getAssets() {
		return assets;
	}
	public void setAssets(ArrayList<Square> assets) {
		this.assets = assets;
	}
	// End - Assets Getter and Setter
	
	// Game Location Getter and Setter
	public Integer getGame_location() {
		return game_location;
	}
	public void setGame_location(Integer game_location) {
		this.game_location = game_location;
	}
	// End - Game Location Getter and Setter
	
	//Release From Prison Card Getter and Setter
	public Boolean getRelease_from_prison_card() {
		return release_from_prison_card;
	}
	public void setRelease_from_prison_card(Boolean release_from_prison_card) {
		this.release_from_prison_card = release_from_prison_card;
	}
	// End - Release From Prison Card Getter and Setter
	
	// Is in Prison Getter and Setter
	public Boolean getIs_in_prison() {
		return is_in_prison;
	}
	public void setIs_in_prison(Boolean is_in_preson) {
		this.is_in_prison = is_in_preson;
	}
	// End - Is in Prison Getter and Setter
	
	// Is in Parking Getter and Setter
	public Boolean getIs_parking() {
		return is_parking;
	}
	public void setIs_parking(Boolean is_parking) {
		this.is_parking = is_parking;
	}
	public void setGetoutOfPrisonCard(Boolean card){//saves release from prison card
		this.release_from_prison_card=card;
	}
	// End - Is in Parking Getter and Setter
	
	@Override
	public String toString() 
	{
		// Display the Players Information
		return MessageFormat.format("\nPlayer Name: {0}\n" +
				"{0}'\'s Funds: {1}\n" +
				"{0}'\'s Assets: {2}\n" +
				"{0}'\'s Location: {3}\n", name, funds, printAssets(), 
				Monopol.getSquareName(game_location).toString());
	}
	
	/**
	 * @return A String with the Formated Assets
	 */
	private String printAssets()
	{
		Double sumTotal = 0.0;
		String ret = "\n";
		
		for(Square asset :assets)
		{
			ret += asset.getName() + " (" + asset.getStay_price() + ")\n";
			sumTotal += asset.getStay_price();
		}
		return ret + "Total Assets Worth: " + sumTotal +"\n";
	}
	
	/**
	 * Calculates the Player next Game Square Location
	 * @param gameCubes The Result of the Game Cubes
	 * @return The Next Game Location
	 */
	public Integer calcGameLocation(Integer gameCubes)//changed to public
	{
		// Set a new temporary Integer
		Integer loc = new Integer(0);
		// Calculate the Game Location with 36 Squares
		loc = (game_location + gameCubes)%36;
		// Check if the Player passed the Start Square and Add to Funds
		// Return the Updated Game Location
		return loc;
	}
	
	/**
	 * Buy The Asset
	 * @param Square An Asset to buyAsset
	 */
	public void buyAsset(Negotiable square)
	{
		this.assets.add((Square)square);
	}
	
	/**
	 * Sell an Asset
	 * @param negotiable An Asset to sell
	 */
	public void sellAsset(Negotiable negotiable, Integer sellPrice)
	{
		// Check if the Asset can be sold and Sell it
		if(negotiable.isSellable())
			negotiable.sell(this);
	}
	
	/**
	 * This Function Delete all the Players' Assets
	 * The Function returns the Assets back to the game and clears the Players' Assets
	 */
	public void deleteAssets()
	{
		// Loop over the Players' assets
		for(Iterator<Square> itr = assets.iterator(); itr.hasNext();)
		{
			// Get the Next Iterator
			Square asset = itr.next();
			// Delete each Asset from its owner
			asset.deleteOwner();
			// Remove from list
			itr.remove();
		}
	}
	
	
	/**
	 * Identify whether the Player is human or non human
	 * @return Abstract
	 */
	public Boolean isHuman() 
	{
		return null;
	}


	/**
	 * @param toDelete the toDelete to set
	 */
	public void setToDelete(Boolean toDelete) {
		this.toDelete = toDelete;
	}


	/**
	 * @return the toDelete
	 */
	public Boolean getToDelete() {
		return toDelete;
	}
	
	public Color getColor()
	{
		return playerColor;
	}


	
}
